home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / sps / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-07-21  |  46.3 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i061:  SPS for BSD, Ultrix1.2, Sun3.x, NFS, Part02/03
  5. Message-ID: <690@uunet.UU.NET>
  6. Date: 23 Jul 87 00:19:21 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1518
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: robert@hslrswi.UUCP (Robert Ward)
  12. Posting-Number: Volume 10, Issue 61
  13. Archive-name: sps/Part02
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 3)."
  22. # Contents:  flagdecode.c getcmd.c globals2.c inittty.c needed.c
  23. #   printproc.c sps.h waitingfor.c
  24. # Wrapped by rs@uunet on Wed Jul 22 20:09:09 1987
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f flagdecode.c -a "${1}" != "-c" ; then 
  27.   echo shar: Will not over-write existing file \"flagdecode.c\"
  28. else
  29. echo shar: Extracting \"flagdecode.c\" \(5436 characters\)
  30. sed "s/^X//" >flagdecode.c <<'END_OF_flagdecode.c'
  31. X# include       "sps.h"
  32. X# include       "flags.h"
  33. X
  34. X/* FLAGDECODE - Looks at the argument list and sets various internal switches */
  35. Xflagdecode ( argc, argv )
  36. X
  37. Xregister int                    argc ;
  38. Xregister char                   **argv ;
  39. X
  40. X{
  41. X    register char           *chp ;
  42. X    union flaglist          *plist ;
  43. X    union flaglist          *tlist ;
  44. X    union flaglist          *ulist ;
  45. X    static char             usage[] =
  46. X    "sps - Unknown option %s\nUsage - sps [ -defgijkoqrsvwyABFNPSTUWZ ][ process|tty|user ] ...\n";
  47. X    union flaglist          *getflgsp() ;
  48. X    extern struct flags     Flg ;
  49. X
  50. X    plist = tlist = ulist = (union flaglist*)0 ;
  51. X    for ( argv++ ; --argc ; argv++ )
  52. X    {
  53. X        chp = *argv ;
  54. X        while ( *chp )
  55. X            switch ( *chp++ )
  56. X            {
  57. X                case '-' :
  58. X                    /* Separation character */
  59. X                    continue ;
  60. X                case 'd' :
  61. X                case 'D' :
  62. X                    /* List disc orientated information */
  63. X                    Flg.flg_d = 1 ;
  64. X                    Flg.flg_v = 0 ;
  65. X                    continue ;
  66. X                case 'e' :
  67. X                case 'E' :
  68. X                    /* List environment strings */
  69. X                    Flg.flg_e = 1 ;
  70. X                    continue ;
  71. X                case 'f' :
  72. X                    /* List the father's process id */
  73. X                    Flg.flg_f = 1 ;
  74. X                    continue ;
  75. X                case 'g' :
  76. X                case 'G' :
  77. X                    /* List the process group id */
  78. X                    Flg.flg_g = 1 ;
  79. X                    continue ;
  80. X                case 'i' :
  81. X                case 'I' :
  82. X                    /* Initialise (super-user only) */
  83. X                    Flg.flg_i = 1 ;
  84. X                    continue ;
  85. X                case 'j' :
  86. X                case 'J' :
  87. X                    /* The next argument specifies the
  88. X                       name of the information file */
  89. X                    if ( argc <= 1 )
  90. X                        prexit(
  91. X          "sps - Name of an information file expected after `-j' flag\n" ) ;
  92. X                    argc-- ;
  93. X                    Flg.flg_j = *++argv ;
  94. X                    continue ;
  95. X                case 'k' :
  96. X                case 'K' :
  97. X                    /* Use a disc file such as /vmcore
  98. X                       rather than /dev/{k}mem for
  99. X                       accessing kernel data. The next
  100. X                       argument specifies the file name. */
  101. X                    if ( argc <= 1 )
  102. X                        prexit(
  103. X           "sps - Name of a memory dump file expected after `-k' flag\n" ) ;
  104. X                    argc-- ;
  105. X                    Flg.flg_k = *++argv ;
  106. X                    Flg.flg_o = 1 ;
  107. X                    continue ;
  108. X                case 'l' :
  109. X                case 'v' :
  110. X                case 'L' :
  111. X                case 'V' :
  112. X                    /* Verbose output */
  113. X                    Flg.flg_d = 0 ;
  114. X                    Flg.flg_v = 1 ;
  115. X                    continue ;
  116. X                case 'o' :
  117. X                case 'O' :
  118. X                    /* Avoid looking at the swap device */
  119. X                    Flg.flg_o = 1 ;
  120. X                    continue ;
  121. X                case 'q' :
  122. X                case 'Q' :
  123. X                    /* Show only the user time, not the
  124. X                       user + system times together. */
  125. X                    Flg.flg_q = 1 ;
  126. X                    continue ;
  127. X                case 'r' :
  128. X                case 'R' :
  129. X                    /* Repeat output every n seconds.
  130. X                       The next argument specifies n which
  131. X                       defaults to 5 if omitted. */
  132. X                    Flg.flg_r = 1 ;
  133. X                    if ( argc > 1 )
  134. X                    {
  135. X                        if ( **++argv >= '0'
  136. X                        && **argv <= '9' )
  137. X                        {
  138. X                            argc-- ;
  139. X                            Flg.flg_rdelay
  140. X                                   = atoi( *argv ) ;
  141. X                            continue ;
  142. X                        }
  143. X                        argv-- ;
  144. X                    }
  145. X                    Flg.flg_rdelay = 0 ;
  146. X                    continue ;
  147. X                case 's' :
  148. X                    /* Next argument specifies a symbol
  149. X                       file rather than the default
  150. X                       /vmunix. */
  151. X                    if ( argc <= 1 )
  152. X                        prexit(
  153. X            "sps - Name of a symbol file expected after `-s' flag\n" ) ;
  154. X                    argc-- ;
  155. X                    Flg.flg_s = *++argv ;
  156. X                    continue ;
  157. X                case 'w' :
  158. X                    /* Wide output, exceeding 79 columns */
  159. X                    Flg.flg_w = 1 ;
  160. X                    continue ;
  161. X                case 'y' :
  162. X                case 'Y' :
  163. X                    /* List current tty information */
  164. X                    Flg.flg_y = 1 ;
  165. X                    continue ;
  166. X                case 'a' :
  167. X                case 'A' :
  168. X                    /* List all processes */
  169. X                    Flg.flg_AZ = 1 ;
  170. X                    Flg.flg_A = 1 ;
  171. X                    continue ;
  172. X                case 'b' :
  173. X                case 'B' :
  174. X                    /* List only busy processes */
  175. X                    Flg.flg_AZ = 1 ;
  176. X                    Flg.flg_B = 1 ;
  177. X                    continue ;
  178. X                case 'F' :
  179. X                    /* List only foreground processes */
  180. X                    Flg.flg_AZ = 1 ;
  181. X                    Flg.flg_F = 1 ;
  182. X                    continue ;
  183. X                case 'n' :
  184. X                case 'N' :
  185. X                    /* No processes, just the summary line*/
  186. X                    Flg.flg_AZ = 1 ;
  187. X                    Flg.flg_N = 1 ;
  188. X                    continue ;
  189. X                case 'p' :
  190. X                case 'P' :
  191. X                    /* List only the given process ids */
  192. X                    Flg.flg_AZ = 1 ;
  193. X                    Flg.flg_P = 1 ;
  194. X                    if ( !plist )
  195. X                       plist=Flg.flg_Plist=getflgsp( argc );
  196. X                    while ( argc > 1 )
  197. X                    {
  198. X                        if ( **++argv == '-' )
  199. X                        {
  200. X                            --argv ;
  201. X                            break ;
  202. X                        }
  203. X                        --argc ;
  204. X                        plist->f_chp = *argv ;
  205. X                        (++plist)->f_chp = (char*)0 ;
  206. X                    }
  207. X                    continue ;
  208. X                case 'S' :
  209. X                    /* List only stopped processes */
  210. X                    Flg.flg_AZ = 1 ;
  211. X                    Flg.flg_S = 1 ;
  212. X                    continue ;
  213. X                case 't' :
  214. X                case 'T' :
  215. X                    /* List only processes attached to the
  216. X                       specified terminals */
  217. X                    Flg.flg_AZ = 1 ;
  218. X                    Flg.flg_T = 1 ;
  219. X                    if ( !tlist )
  220. X                       tlist=Flg.flg_Tlist=getflgsp( argc );
  221. X                    while ( argc > 1 )
  222. X                    {
  223. X                        if ( **++argv == '-' )
  224. X                        {
  225. X                            --argv ;
  226. X                            break ;
  227. X                        }
  228. X                        --argc ;
  229. X                        tlist->f_chp = *argv ;
  230. X                        (++tlist)->f_chp = (char*)0 ;
  231. X                    }
  232. X                    continue ;
  233. X                case 'u' :
  234. X                case 'U' :
  235. X                    /* List only processes belonging to the
  236. X                       specified users */
  237. X                    Flg.flg_AZ = 1 ;
  238. X                    Flg.flg_U = 1 ;
  239. X                    if ( !ulist )
  240. X                       ulist=Flg.flg_Ulist=getflgsp( argc );
  241. X                    while ( argc > 1 )
  242. X                    {
  243. X                        if ( **++argv == '-' )
  244. X                        {
  245. X                            --argv ;
  246. X                            break ;
  247. X                        }
  248. X                        --argc ;
  249. X                        ulist->f_chp = *argv ;
  250. X                        (++ulist)->f_chp = (char*)0 ;
  251. X                    }
  252. X                    continue ;
  253. X                case 'W' :
  254. X                    /* List only waiting processes */
  255. X                    Flg.flg_AZ = 1 ;
  256. X                    Flg.flg_W = 1 ;
  257. X                    continue ;
  258. X                case 'z' :
  259. X                case 'Z' :
  260. X                    /* List only zombie processes */
  261. X                    Flg.flg_AZ = 1 ;
  262. X                    Flg.flg_Z = 1 ;
  263. X                    continue ;
  264. X                default :
  265. X                    prexit( usage, *argv ) ;
  266. X                    /* NOTREACHED */
  267. X            }
  268. X    }
  269. X}
  270. END_OF_flagdecode.c
  271. if test 5436 -ne `wc -c <flagdecode.c`; then
  272.     echo shar: \"flagdecode.c\" unpacked with wrong size!
  273. fi
  274. # end of overwriting check
  275. fi
  276. if test -f getcmd.c -a "${1}" != "-c" ; then 
  277.   echo shar: Will not over-write existing file \"getcmd.c\"
  278. else
  279. echo shar: Extracting \"getcmd.c\" \(4980 characters\)
  280. sed "s/^X//" >getcmd.c <<'END_OF_getcmd.c'
  281. X# include       "sps.h"
  282. X# include       "flags.h"
  283. X# include       <h/vm.h>
  284. X# ifdef BSD42
  285. X# include    <machine/pte.h>
  286. X# else
  287. X# include       <h/pte.h>
  288. X# endif
  289. X
  290. X/*
  291. X** GETCMD - Returns a character string read from a process' upage.
  292. X** This character string should represent the arguments to the current process.
  293. X*/
  294. Xchar    *getcmd ( p )
  295. X
  296. Xregister struct process         *p ;
  297. X
  298. X{
  299. X    register int            *ip ;
  300. X    register char           *cp ;
  301. X    register char           *cp0 ;
  302. X    unsigned                nbad ;
  303. X    struct dblock           db ;
  304. X    struct pte              ptetbl[ UPAGES + CLSIZE ] ;
  305. X    union
  306. X    {
  307. X        char            a_argc[ CLSIZE * NBPG ] ;
  308. X        int             a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
  309. X    } argbuf ;
  310. X    extern struct flags     Flg ;
  311. X    extern union userstate  User ;
  312. X    extern int              Flmem, Flswap ;
  313. X    char                    *strcat(), *strncpy(), *strsave() ;
  314. X
  315. X    p->pr_csaved = 0 ;
  316. X    p->pr_upag = 0 ;
  317. X    if ( p->pr_p.p_stat == SZOMB )
  318. X        return ( "** Exit **" ) ;
  319. X    if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
  320. X        return ( "** Swapped out **" ) ;
  321. X    /* Find the process' upage */
  322. X    if ( !getupage( p, ptetbl ) )           
  323. X        return ( "** No upage **" ) ;
  324. X    /* Is this a system process ? */
  325. X    if ( p->pr_p.p_flag & SSYS )            
  326. X        switch ( p->pr_p.p_pid )
  327. X        {
  328. X            case 0 :
  329. X                p->pr_upag = 1 ;
  330. X                return ( "Unix Swapper" ) ;
  331. X            case 2 :
  332. X                p->pr_upag = 1 ;
  333. X                return ( "Unix Pager" ) ;
  334. X            default :
  335. X                break ;
  336. X        }
  337. X    /* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  338. X    /* Check for lack of stack, jack! (Sun 3.0 biod's) */
  339. X    if (User.u_us.u_ssize == 0)
  340. X        goto getsysargs ;
  341. X    /* Look at the top of the upage to locate the command arguments.
  342. X       The page is loaded if the process itself is loaded and the pte
  343. X       contains is marked as valid. */
  344. X    if ( (p->pr_p.p_flag & SLOAD)
  345. X    && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
  346. X    {       /* If the page is loaded, read the arguments from
  347. X           physical memory. */
  348. X        memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
  349. X        if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  350. X            return ( "** Memory read error **" ) ;
  351. X    }
  352. X    else                            
  353. X    {       /* Otherwise the page is on the swap device */
  354. X        vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
  355. X# ifdef BSD42
  356. X        swseek( (long)dtob( db.db_base ) ) ;
  357. X# else
  358. X        swseek( (long)ctob( db.db_base ) ) ;
  359. X# endif
  360. X        if ( Flg.flg_o )
  361. X            return ( "** Swapped page **" ) ;
  362. X        if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  363. X            return ( "** Swap device read error **" ) ;
  364. X    }
  365. X    /* Look down until the end of command arguments is found. */
  366. X    p->pr_upag = 1 ;
  367. X    p->pr_csaved = 1 ;
  368. X    ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
  369. X    ip -= 2 ;
  370. X    while ( *--ip )
  371. X        if ( ip == &argbuf.a_argi[0] )
  372. X            goto getsysargs ;
  373. X    /* Process the command arguments, looking for nulls and unprintable
  374. X       characters. */
  375. X    cp0 = (char*)(ip + 1) ;
  376. X    if ( !*cp0 )                    
  377. X        cp0++ ;                 
  378. X    if ( *cp0 )
  379. X    {
  380. X        nbad = 0 ;                      
  381. X        for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
  382. X        {
  383. X            *cp &= 0177 ;
  384. X            if ( !*cp )             
  385. X            {       /* Replace nulls with spaces */
  386. X                *cp = ' ' ;
  387. X                continue ;
  388. X            }
  389. X            if ( *cp < ' ' || *cp == 0177 )
  390. X            {       /* Replace control characters with ?'s */
  391. X                if ( ++nbad > 5 )
  392. X                {
  393. X                    *cp++ = ' ' ;
  394. X                    break ;
  395. X                }
  396. X                *cp = '?' ;
  397. X                continue ;
  398. X            }
  399. X            if ( !Flg.flg_e && *cp == '=' )
  400. X            {       /* Break on an `=' if we are not interested
  401. X                   in the environment strings. */
  402. X                *cp = '\0' ;
  403. X                while ( cp > cp0 && *--cp != ' ' )
  404. X                    *cp = '\0' ;
  405. X                break ;
  406. X            }
  407. X        }
  408. X        while ( *--cp == ' ' )
  409. X            *cp = '\0' ;
  410. X        return ( strsave( cp0 ) ) ;
  411. X    }
  412. Xgetsysargs :
  413. X    /* If the command arguments cannot be accessed from the user's memory
  414. X       space, get the command name from the system's idea of what the
  415. X       name should be. */
  416. X    argbuf.a_argc[0] = '(' ;
  417. X    (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
  418. X        sizeof( User.u_us.u_comm ) ) ;
  419. X    (void)strcat( &argbuf.a_argc[0], ")" ) ;
  420. X    return ( strsave( argbuf.a_argc ) ) ;
  421. X}
  422. X
  423. X/*
  424. X** VSTODB - Given a base/size pair in virtual swap area,
  425. X** return a physical base/size pair which is the
  426. X** (largest) initial, physically contiguous block.
  427. X/* This code is stolen from the kernel file /sys/sys/vm_drum.c.
  428. X*/
  429. Xvstodb ( vsbase, vssize, dmp, dbp, rev )
  430. X
  431. Xregister int                    vsbase ;
  432. Xregister int                    vssize;
  433. Xstruct dmap                     *dmp ;
  434. Xregister struct dblock          *dbp ;
  435. Xint                             rev ;
  436. X
  437. X{
  438. X    register int            blk ;
  439. X    register swblk_t        *ip ;
  440. X# ifdef BSD42
  441. X    extern struct info      Info ;
  442. X# endif
  443. X
  444. X# ifdef BSD42
  445. X    blk = Info.i_dmmin ;
  446. X# else
  447. X    blk = DMMIN ;
  448. X# endif
  449. X    ip = dmp->dm_map ;
  450. X    while ( vsbase >= blk )
  451. X    {
  452. X        vsbase -= blk ;
  453. X# ifdef BSD42
  454. X        if ( blk < Info.i_dmmax )
  455. X# else
  456. X        if ( blk < DMMAX )
  457. X# endif
  458. X            blk *= 2 ;
  459. X        ip++ ;
  460. X    }
  461. X    dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
  462. X    dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
  463. X}
  464. END_OF_getcmd.c
  465. if test 4980 -ne `wc -c <getcmd.c`; then
  466.     echo shar: \"getcmd.c\" unpacked with wrong size!
  467. fi
  468. # end of overwriting check
  469. fi
  470. if test -f globals2.c -a "${1}" != "-c" ; then 
  471.   echo shar: Will not over-write existing file \"globals2.c\"
  472. else
  473. echo shar: Extracting \"globals2.c\" \(5375 characters\)
  474. sed "s/^X//" >globals2.c <<'END_OF_globals2.c'
  475. X# include       "sps.h"
  476. X
  477. X/* Read Only variables, global to the code of sps ... */
  478. X
  479. X/* Null ttyline device ... */
  480. Xstruct ttyline                  Notty = { 0, 0, "  ", 0 } ;
  481. X
  482. X/*
  483. X** The symbol table. For each address read from the kernel during
  484. X** initialisation, this table shows the following:
  485. X**      i.   the name of that symbol within the kernel ;
  486. X**      ii.  whether an extra indirection is needed through the kernel,
  487. X**           i.e. whether the value of that symbol should be obtained
  488. X**           rather than its address.
  489. X**      iii. where the obtained value/address is placed in the Info structure ;
  490. X**      iv.  whether the obtained value is associated with a reason for
  491. X**           a process wait state.
  492. X*/
  493. X/* The order of entries in this table is unimportant. */
  494. X
  495. Xextern struct info              Info ;
  496. X
  497. Xstruct symbol   Symbollist[] =
  498. X{       
  499. X    /* Kernel addresses required in order to access process,
  500. X       tty and upage information. All these addresses should be
  501. X       located in the symbol file during initialisation. */
  502. X    { "_proc",      1,  (caddr_t*)&Info.i_proc0,    (char*)0        },
  503. X    { "_nproc",     1,  (caddr_t*)&Info.i_nproc,    (char*)0        },
  504. X    { "_text",      1,  (caddr_t*)&Info.i_text0,    (char*)0        },
  505. X    { "_ntext",     1,  (caddr_t*)&Info.i_ntext,    (char*)0        },
  506. X    { "_inode",     1,  (caddr_t*)&Info.i_inode0,   (char*)0        },
  507. X    { "_ninode",    1,  (caddr_t*)&Info.i_ninode,   (char*)0        },
  508. X    { "_swbuf",     1,  (caddr_t*)&Info.i_swbuf0,   (char*)0        },
  509. X    { "_nswbuf",    1,  (caddr_t*)&Info.i_nswbuf,   (char*)0        },
  510. X    { "_buf",       1,  (caddr_t*)&Info.i_buf0,     (char*)0        },
  511. X    { "_nbuf",      1,  (caddr_t*)&Info.i_nbuf,     (char*)0        },
  512. X    { "_ecmx",      1,  (caddr_t*)&Info.i_ecmx,     (char*)0        },
  513. X    { "_Usrptmap",  0,  (caddr_t*)&Info.i_usrptmap, (char*)0        },
  514. X    { "_usrpt",     0,  (caddr_t*)&Info.i_usrpt,    (char*)0        },
  515. X    { "_cdevsw",    0,  (caddr_t*)&Info.i_cdevsw,   (char*)0        },
  516. X# ifdef BSD42
  517. X# ifndef NFS
  518. X    { "_quota",     1,  (caddr_t*)&Info.i_quota0,   (char*)0        },
  519. X    { "_nquota",    1,  (caddr_t*)&Info.i_nquota,   (char*)0        },
  520. X# endif NFS
  521. X    { "_dmmin",     1,  (caddr_t*)&Info.i_dmmin,    (char*)0        },
  522. X    { "_dmmax",     1,  (caddr_t*)&Info.i_dmmax,    (char*)0        },
  523. X    { "_mbutl",     0,  (caddr_t*)&Info.i_mbutl,    (char*)0        },
  524. X# else
  525. X    { "_hz",        1,  (caddr_t*)&Info.i_hz,       (char*)0        },
  526. X# endif BSD42
  527. X# ifdef CHAOS
  528. X    { "_Chconntab", 0,  &Info.i_Chconntab,          (char*)0        },
  529. X# endif CHAOS
  530. X    /* Kernel addresses associated with process wait states.
  531. X       It is not important if some of these addresses are unresolved
  532. X       at initialisation. */
  533. X# ifndef SUN
  534. X    { "_fltab",     0,  &Info.i_waitstate[0],       "floppy"        },
  535. X    { "_tu",        0,  &Info.i_waitstate[1],       "tu58"          },
  536. X    { "_lp_softc",  0,  &Info.i_waitstate[3],       "printr"        },
  537. X# endif SUN
  538. X    { "_bfreelist", 0,  &Info.i_waitstate[2],       "buffer"        },
  539. X    { "_lbolt",     0,  &Info.i_waitstate[4],       "lbolt"         },
  540. X    { "_runin",     0,  &Info.i_waitstate[5],       "runin"         },
  541. X    { "_runout",    0,  &Info.i_waitstate[6],       "runout"        },
  542. X    { "_ipc",       0,  &Info.i_waitstate[7],       "ptrace"        },
  543. X    { "_u",         0,  &Info.i_waitstate[8],       "pause"         },
  544. X    { "_freemem",   0,  &Info.i_waitstate[9],       "freemm"        },
  545. X    { "_kernelmap", 0,  &Info.i_waitstate[10],      "kermap"        },
  546. X    { "_cwaiting",  0,  &Info.i_waitstate[11],      "cwait"         },
  547. X# ifdef BSD42
  548. X    { "_selwait",   0,  &Info.i_waitstate[12],      "select"        },
  549. X# endif BSD42
  550. X# ifdef CHAOS
  551. X    { "_Chrfclist", 0,  &Info.i_waitstate[13],      "chrfc"         },
  552. X# endif
  553. X# ifndef SUN
  554. X    { "_rhpbuf",    0,  &Info.i_waitstate[14],      "rhpbuf"        },
  555. X    { "_rhtbuf",    0,  &Info.i_waitstate[15],      "rhtbuf"        },
  556. X    { "_ridcbuf",   0,  &Info.i_waitstate[16],      "ridcbf"        },
  557. X    { "_rikbuf",    0,  &Info.i_waitstate[17],      "rikbuf"        },
  558. X    { "_rmtbuf",    0,  &Info.i_waitstate[18],      "rmtbuf"        },
  559. X    { "_rrkbuf",    0,  &Info.i_waitstate[19],      "rrkbuf"        },
  560. X    { "_rrlbuf",    0,  &Info.i_waitstate[20],      "rrlbuf"        },
  561. X    { "_rrxbuf",    0,  &Info.i_waitstate[21],      "rrxbuf"        },
  562. X    { "_rswbuf",    0,  &Info.i_waitstate[22],      "rswbuf"        },
  563. X    { "_rtmbuf",    0,  &Info.i_waitstate[23],      "rtmbuf"        },
  564. X    { "_rtsbuf",    0,  &Info.i_waitstate[24],      "rtsbuf"        },
  565. X    { "_rudbuf",    0,  &Info.i_waitstate[25],      "rudbuf"        },
  566. X    { "_rupbuf",    0,  &Info.i_waitstate[26],      "rupbuf"        },
  567. X    { "_rutbuf",    0,  &Info.i_waitstate[27],      "rutbuf"        },
  568. X    { "_rvabuf",    0,  &Info.i_waitstate[28],      "rvabuf"        },
  569. X    { "_rvpbuf",    0,  &Info.i_waitstate[29],      "rvpbuf"        },
  570. X    { "_chtbuf",    0,  &Info.i_waitstate[30],      "chtbuf"        },
  571. X    { "_cmtbuf",    0,  &Info.i_waitstate[31],      "cmtbuf"        },
  572. X    { "_ctmbuf",    0,  &Info.i_waitstate[32],      "ctmbuf"        },
  573. X    { "_ctsbuf",    0,  &Info.i_waitstate[33],      "ctsbuf"        },
  574. X    { "_cutbuf",    0,  &Info.i_waitstate[34],      "cutbuf"        },
  575. X# else
  576. X    { "_async_bufhead", 0,  &Info.i_waitstate[14],  "async"        },
  577. X    { "_desktops",    0,  &Info.i_waitstate[15],    "dtops"        },
  578. X# endif SUN
  579. X    { (char*)0,     0,  (caddr_t*)0,                (char*)0        }
  580. X} ;
  581. END_OF_globals2.c
  582. if test 5375 -ne `wc -c <globals2.c`; then
  583.     echo shar: \"globals2.c\" unpacked with wrong size!
  584. fi
  585. # end of overwriting check
  586. fi
  587. if test -f inittty.c -a "${1}" != "-c" ; then 
  588.   echo shar: Will not over-write existing file \"inittty.c\"
  589. else
  590. echo shar: Extracting \"inittty.c\" \(3572 characters\)
  591. sed "s/^X//" >inittty.c <<'END_OF_inittty.c'
  592. X# include       "sps.h"
  593. X# include       <h/conf.h>
  594. X# include       <h/ioctl.h>
  595. X# include       <h/tty.h>
  596. X# include       <sys/stat.h>
  597. X# include       <stdio.h>
  598. X
  599. X/* INITTTY - Initialise the tty part of the info structure */
  600. Xinittty ()
  601. X{
  602. X    register struct ttyline *lp ;
  603. X# ifdef BSD42
  604. X    register struct direct  *dp ;
  605. X    DIR                     *dfd ;
  606. X# else
  607. X    struct direct           dir ;
  608. X    FILE                    *dfd ;
  609. X# endif
  610. X    struct stat             statbuf ;
  611. X    static char             filedev[] = FILE_DEV ;
  612. X    extern struct info      Info ;
  613. X    extern int              Flkmem ;
  614. X# ifdef BSD42
  615. X    DIR                     *opendir() ;
  616. X    struct direct           *readdir() ;
  617. X# else
  618. X    FILE                    *fopen() ;
  619. X# endif
  620. X
  621. X    lp = Info.i_ttyline ;
  622. X# ifdef BSD42
  623. X    if ( !(dfd = opendir( filedev )) )
  624. X# else
  625. X    if ( !(dfd = fopen( filedev, "r" )) )
  626. X# endif
  627. X        prexit( "Can't open %s\n", filedev ) ;
  628. X    if ( chdir( filedev ) < 0 )
  629. X        prexit( "sps - Can't chdir to %s\n", filedev ) ;
  630. X# ifdef BSD42
  631. X    /* Read all entries in the device directory, looking for ttys */
  632. X    while ( dp = readdir( dfd ) )
  633. X    {       /* Skip entries that do not match "tty" or "console" */
  634. X        if ( strncmp( "tty", dp->d_name, 3 )
  635. X        &&   strcmp( "console", dp->d_name ) )
  636. X            continue ;
  637. X        /* Skip "tty" itself */
  638. X        if ( dp->d_namlen == 3 )
  639. X            continue ;
  640. X# ifdef CHAOS
  641. X        /* Skip chaos ttys ; they are accessed during ttystatus() */
  642. X        if ( dp->d_namelen > 3 &&
  643. X        dp->d_name[ sizeof( "tty" ) - 1 ] == 'C' )
  644. X            continue ;
  645. X# endif
  646. X        if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
  647. X            prexit( "sps - Too many ttys in %s\n", filedev ) ;
  648. X        /* Copy the tty name into the information entry */
  649. X        if ( !strcmp( dp->d_name, "console" ) )
  650. X        {
  651. X            lp->l_name[0] = 'c' ;
  652. X            lp->l_name[1] = 'o' ;
  653. X        }
  654. X        else
  655. X        {
  656. X            lp->l_name[0] = dp->d_name[3] ;
  657. X            lp->l_name[1] = dp->d_name[4] ;
  658. X        }
  659. X        /* Ensure that this tty is actually a valid character device */
  660. X        if ( stat( dp->d_name, &statbuf ) < 0 )
  661. X            continue ;
  662. X# else
  663. X    /* Read all entries in the device directory, looking for ttys */
  664. X    while ( fread( (char*)&dir, sizeof( struct direct ), 1, dfd ) == 1 )
  665. X    {       /* Skip entries that do not match "tty" or "console" */
  666. X        if ( strncmp( "tty", dir.d_name, 3 )
  667. X        &&   strcmp( "console", dir.d_name ) )
  668. X            continue ;
  669. X        /* Skip "tty" itself */
  670. X        if ( dir.d_name[3] == '\0' )
  671. X            continue ;
  672. X# ifdef CHAOS
  673. X        /* Skip chaos ttys ; they are accessed during ttystatus() */
  674. X        if ( dir.d_name[ sizeof( "tty" ) - 1 ] == 'C' )
  675. X            continue ;
  676. X# endif
  677. X        if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
  678. X            prexit( "sps - Too many ttys in %s\n", filedev ) ;
  679. X        /* Copy the tty name into the information entry */
  680. X        if ( !strcmp( dir.d_name, "console" ) )
  681. X        {
  682. X            lp->l_name[0] = 'c' ;
  683. X            lp->l_name[1] = 'o' ;
  684. X        }
  685. X        else
  686. X        {
  687. X            lp->l_name[0] = dir.d_name[3] ;
  688. X            lp->l_name[1] = dir.d_name[4] ;
  689. X        }
  690. X        /* Ensure that this tty is actually a valid character device */
  691. X        if ( stat( dir.d_name, &statbuf ) < 0 )
  692. X            continue ;
  693. X# endif
  694. X        if ( (statbuf.st_mode & S_IFMT) != S_IFCHR )
  695. X            continue ;
  696. X        /* Find the device # of the tty and the address of its
  697. X           associated struct tty in /dev/kmem. */
  698. X        lp->l_dev = statbuf.st_rdev ;
  699. X        memseek( Flkmem,
  700. X             (long)&Info.i_cdevsw[ major( statbuf.st_rdev ) ].d_ttys ) ;
  701. X        if ( read( Flkmem, (char*)&lp->l_addr, sizeof( lp->l_addr ) )
  702. X        != sizeof( lp->l_addr ) )
  703. X        {
  704. X            fprintf( stderr, "sps - Can't read struct tty for %s\n",
  705. X# ifdef BSD42
  706. X                dp->d_name ) ;
  707. X# else
  708. X                dir.d_name ) ;
  709. X# endif
  710. X            continue ;
  711. X        }
  712. X        lp->l_addr += (int)minor( statbuf.st_rdev ) ;
  713. X        lp++ ;
  714. X    }
  715. X# ifdef BSD42
  716. X    (void)closedir( dfd ) ;
  717. X# else
  718. X    (void)fclose( dfd ) ;
  719. X# endif
  720. X}
  721. END_OF_inittty.c
  722. if test 3572 -ne `wc -c <inittty.c`; then
  723.     echo shar: \"inittty.c\" unpacked with wrong size!
  724. fi
  725. # end of overwriting check
  726. fi
  727. if test -f needed.c -a "${1}" != "-c" ; then 
  728.   echo shar: Will not over-write existing file \"needed.c\"
  729. else
  730. echo shar: Extracting \"needed.c\" \(4455 characters\)
  731. sed "s/^X//" >needed.c <<'END_OF_needed.c'
  732. X# include       "sps.h"
  733. X# include       "flags.h"
  734. X# include       <h/text.h>
  735. X# include       <stdio.h>
  736. X
  737. X/*
  738. X** NEEDED - Determine which processes are needed for the printout
  739. X** and add these to a list of needed processes.
  740. X*/
  741. Xstruct process  *needed ( process, text )
  742. X
  743. Xregister struct process         *process ;
  744. Xstruct text                     *text ;
  745. X
  746. X{
  747. X    register struct process *p ;
  748. X    register struct process *plist ;
  749. X    struct process          *lastp ;
  750. X    int                     uid ;
  751. X    extern struct flags     Flg ;
  752. X    extern union userstate  User ;
  753. X    extern struct info      Info ;
  754. X    extern struct ttyline   Notty ;
  755. X    struct ttyline          *findtty() ;
  756. X    char                    *getcmd() ;
  757. X
  758. X    plist = (struct process*)0 ;
  759. X    lastp = &process[ Info.i_nproc ] ;
  760. X    /* Normalise internal pointers from kernel addresses. For each kmem
  761. X       address in the `proc' and `text' structures, we convert that
  762. X       address for our own internal use. */
  763. X    for ( p = process ; p < lastp ; p++ )
  764. X    {                               
  765. X        if ( !p->pr_p.p_stat )  
  766. X            continue ;
  767. X        /* Normalise internal text pointers */
  768. X        if ( p->pr_p.p_textp )
  769. X            p->pr_p.p_textp = &text[p->pr_p.p_textp - Info.i_text0];
  770. X        /* Normalise internal linked list of processes */
  771. X        p->pr_plink = p->pr_p.p_link ?
  772. X            &process[ p->pr_p.p_link  - Info.i_proc0 ] :
  773. X            (struct process*)0 ;
  774. X        /* Normalise internal parent pointers */
  775. X        p->pr_pptr = p->pr_p.p_pptr ?
  776. X            &process[ p->pr_p.p_pptr - Info.i_proc0 ] :
  777. X            (struct process*)0 ;
  778. X        /* Check for valid parent pointers */
  779. X        if ( !p->pr_pptr )
  780. X        {
  781. X            p->pr_pptr = process ;
  782. X            continue ;
  783. X        }
  784. X        if ( p->pr_pptr < process || p->pr_pptr >= lastp )
  785. X        {
  786. X            fprintf( stderr, "sps - process %d has bad pptr\n",
  787. X                p->pr_p.p_pid ) ;
  788. X            p->pr_pptr = process ;
  789. X        }
  790. X    }
  791. X    /* For each process, see if it is a candidate for selection.
  792. X       If so, retrieve its command arguments and upage information. */
  793. X    uid = getuid() ;
  794. X    for ( p = process ; p < lastp ; p++ )
  795. X    {                               
  796. X        if ( !p->pr_p.p_stat )
  797. X            continue ;
  798. X        /* Count processes and sizes */
  799. X        summarise( p ) ;
  800. X        /* Select the given processes. Bear in mind that selection
  801. X           of processes based on the `F' and `T' flags must be
  802. X           postponed until the upage is accessed. */
  803. X        if ( !Flg.flg_F && !Flg.flg_T && !selectproc( p, process, uid ))
  804. X            continue ;
  805. X        /* Try to find the process' command arguments. Accessing the
  806. X           arguments also involves retrieving the upage. */
  807. X        p->pr_cmd = getcmd( p ) ;
  808. X        /* If the upage was found successfully, use this information */
  809. X        if ( p->pr_upag )       
  810. X        {
  811. X# ifdef BSD42
  812. X            p->pr_rself = User.u_us.u_ru ;
  813. X            p->pr_rchild = User.u_us.u_cru ;
  814. X# else
  815. X            p->pr_vself = User.u_us.u_vm ;
  816. X            p->pr_vchild = User.u_us.u_cvm ;
  817. X# endif
  818. X            p->pr_tty = findtty( p ) ;
  819. X            p->pr_files = filecount() ;
  820. X        }
  821. X        else
  822. X            p->pr_tty = &Notty ;
  823. X        /* Select on the basis of the `F' and `T' flags */
  824. X        if ( Flg.flg_F          
  825. X        && !(p->pr_p.p_pgrp && p->pr_p.p_pgrp == p->pr_tty->l_pgrp) )
  826. X            continue ;
  827. X        if ( Flg.flg_T && !selecttty( p ) )
  828. X            continue ;
  829. X        /* Arrive here with a selected process. Add this to the
  830. X           linked list of needed processes. */
  831. X        p->pr_plink = plist ;   
  832. X        plist = p ;
  833. X        p->pr_child = (struct process*)0 ;
  834. X        p->pr_sibling = (struct process*)0 ;
  835. X    }
  836. X    return ( plist ) ;
  837. X}
  838. X
  839. X/* SUMMARISE - Summarises the given process into the `Summary' structure */
  840. X/*
  841. X** SHOULD ACCOUNT HERE FOR THE SIZE OF LOADED PAGE TABLES, BUT WE DON'T REALLY
  842. X** KNOW THEIR RESIDENT SIZES.
  843. X*/
  844. Xsummarise ( p )
  845. X
  846. Xregister struct process         *p ;
  847. X
  848. X{
  849. X    register struct text    *tp ;
  850. X    int                     busy ;
  851. X    extern struct summary   Summary ;
  852. X
  853. X    Summary.sm_ntotal++ ;
  854. X    if ( p->pr_p.p_stat == SZOMB )
  855. X        return ;
  856. X    /* Firstly, account for processes */
  857. X    Summary.sm_ktotal += p->pr_p.p_dsize + p->pr_p.p_ssize ;
  858. X    Summary.sm_kloaded += p->pr_p.p_rssize ;
  859. X    Summary.sm_kswapped += p->pr_p.p_swrss ;
  860. X    if ( p->pr_p.p_flag & SLOAD )
  861. X        Summary.sm_nloaded++ ;
  862. X    else
  863. X        Summary.sm_nswapped++ ;
  864. X    busy = (p->pr_p.p_stat == SRUN) || (p->pr_p.p_stat==SSLEEP
  865. X         && (p->pr_p.p_pri<PZERO && p->pr_p.p_pid > MSPID) ) ;
  866. X    if ( busy )
  867. X    {
  868. X        Summary.sm_nbusy++ ;
  869. X        Summary.sm_kbusy += p->pr_p.p_dsize + p->pr_p.p_ssize ;
  870. X    }
  871. X    /* Now account for their texts */
  872. X    if ( !(tp = p->pr_p.p_textp) || !tp->x_count )
  873. X        return ;                
  874. X    Summary.sm_ktotal += tp->x_size ;
  875. X    Summary.sm_kloaded += tp->x_rssize ;
  876. X    Summary.sm_kswapped += tp->x_swrss ;
  877. X    if ( busy )
  878. X        Summary.sm_kbusy += tp->x_size ;
  879. X    tp->x_count = 0 ;
  880. X}
  881. END_OF_needed.c
  882. if test 4455 -ne `wc -c <needed.c`; then
  883.     echo shar: \"needed.c\" unpacked with wrong size!
  884. fi
  885. # end of overwriting check
  886. fi
  887. if test -f printproc.c -a "${1}" != "-c" ; then 
  888.   echo shar: Will not over-write existing file \"printproc.c\"
  889. else
  890. echo shar: Extracting \"printproc.c\" \(5849 characters\)
  891. sed "s/^X//" >printproc.c <<'END_OF_printproc.c'
  892. X# include       "sps.h"
  893. X# include       "flags.h"
  894. X# include       <h/text.h>
  895. X
  896. X/* PRINTPROC - Pretty print a process according to the switches. */
  897. Xprintproc ( p, md )
  898. X
  899. Xregister struct process         *p ;            
  900. Xint                             md ;            
  901. X
  902. X{
  903. X    register char           *chp ;
  904. X    register struct text    *tp ;
  905. X    register struct hashtab *hp ;
  906. X    char                    chbuf[10] ;
  907. X    time_t                  time ;
  908. X    time_t                  chtime ;
  909. X# ifdef BSD42
  910. X    time_t                  utime ;
  911. X    time_t                  uchtime ;
  912. X# endif
  913. X    extern short            Lastuid, Lastpgrp ;
  914. X    extern struct flags     Flg ;
  915. X    char                    *waitingfor() ;
  916. X    struct hashtab          *hashuid() ;
  917. X    double                  percentmem() ;
  918. X
  919. X    /* List tty name and foreground/background/detached information */
  920. X    printf( "%2.2s%c", p->pr_tty->l_name,
  921. X        !p->pr_p.p_pgrp ? ' ' :
  922. X# ifdef SDETACH
  923. X        p->pr_p.p_flag & SDETACH ? '_' :
  924. X# endif
  925. X        p->pr_p.p_pgrp == p->pr_tty->l_pgrp ? '.' : ' ' ) ;
  926. X    hp = hashuid( (int)p->pr_p.p_uid ) ;
  927. X    if ( !md  )                             
  928. X    {       /* If a top-level process, list the user name */
  929. X        if ( hp )
  930. X            printf( "%-8.8s ", hp->h_uname ) ;
  931. X        else
  932. X            printf( "user%-4.4d ", p->pr_p.p_uid ) ;
  933. X    }
  934. X    else                                    
  935. X    {       /* Usually list an asterisk for a child process */
  936. X        md = md > 8 ? 8 : md ;
  937. X        printf( "%*s%c", md, "",
  938. X            p->pr_p.p_pgrp == Lastpgrp ? '|' : '*' ) ;      
  939. X        /* But beware of setuid processes */
  940. X        md = 8 - md ;
  941. X        if ( p->pr_p.p_uid == Lastuid )
  942. X            printf( "%-*.*s", md, md, "" ) ;
  943. X        else if ( hp )
  944. X            printf( "%-*.*s", md, md, hp->h_uname ) ;
  945. X        else
  946. X        {
  947. X            md -= 4 ;
  948. X            printf( "user%-*.*d", md, md, p->pr_p.p_uid ) ;
  949. X        }
  950. X    }
  951. X    Lastuid = p->pr_p.p_uid ;
  952. X    Lastpgrp = p->pr_p.p_pgrp ;
  953. X    if ( Flg.flg_d )                        
  954. X    {       /* List disc I/O and paging information */
  955. X        if ( !p->pr_upag || p->pr_p.p_stat == SZOMB )
  956. X        {
  957. X            prcmd( p, 49, -63 ) ;
  958. X            return ;
  959. X        }
  960. X        printf( "%2d %8d+%8d %4d %8d %8D ",
  961. X            p->pr_files,
  962. X# ifdef BSD42
  963. X            p->pr_rself.ru_majflt,
  964. X            p->pr_rself.ru_minflt,
  965. X            p->pr_rself.ru_nswap,
  966. X            p->pr_rself.ru_inblock + p->pr_rself.ru_oublock,
  967. X            KBYTES( p->pr_rself.ru_idrss + p->pr_rself.ru_isrss
  968. X                + p->pr_rself.ru_ixrss ) ) ;
  969. X# else
  970. X            p->pr_vself.vm_majflt,
  971. X            p->pr_vself.vm_minflt,
  972. X            p->pr_vself.vm_nswap,
  973. X            p->pr_vself.vm_inblk + p->pr_vself.vm_oublk,
  974. X            KBYTES( (p->pr_vself.vm_idsrss
  975. X                + p->pr_vself.vm_ixrss) / Info.i_hz ) ) ;
  976. X# endif
  977. X        prcmd( p, 5, -63 ) ;
  978. X        return ;
  979. X    }
  980. X    if ( !Flg.flg_v )                       
  981. X    {       /* Not verbose so just list command arguments */
  982. X        prcmd( p, 5, -19 ) ;
  983. X        return ;
  984. X    }
  985. X    /* Arrive here if being verbose ; list cpu information */
  986. X    switch ( p->pr_p.p_stat )               
  987. X    {                                       
  988. X        case SSLEEP :
  989. X        case SWAIT :
  990. X        case SIDL :
  991. X            /* Determine why a process should be in a wait state */
  992. X            chp = waitingfor( p ) ;
  993. X            break ;
  994. X        case SRUN :
  995. X            chp = "run" ;
  996. X            break ;
  997. X        case SZOMB :
  998. X            chp = "exit" ;
  999. X            break ;
  1000. X        case SSTOP :
  1001. X            chp = "stop" ;
  1002. X            break ;
  1003. X    }
  1004. X    /* If the process is loaded, list the status information in capitals */
  1005. X    printf( "%-6.6s ", p->pr_p.p_flag & SLOAD ?
  1006. X        (capitals( chp, chbuf ), chbuf) : chp ) ;
  1007. X    /* List process flags */
  1008. X    printf( "%c%c%c", p->pr_p.p_flag & SSYS ? 'U' :
  1009. X        p->pr_p.p_flag & STRC ? 'T' : ' ',
  1010. X        p->pr_p.p_flag & SVFORK ? 'V' :
  1011. X        p->pr_p.p_flag & SPHYSIO ? 'I' : ' ',
  1012. X        p->pr_p.p_flag & SUANOM ? 'A' : ' ' ) ;
  1013. X    /* List process niceness */
  1014. X    if ( p->pr_p.p_nice != NZERO )          
  1015. X        printf( "%3d ", p->pr_p.p_nice - NZERO ) ;
  1016. X    else
  1017. X        printf( "    " ) ;
  1018. X    if ( p->pr_p.p_stat == SZOMB )
  1019. X    {
  1020. X        prcmd( p, 41, -69 ) ;
  1021. X        return ;
  1022. X    }                                       
  1023. X    /* List process and text virtual sizes */
  1024. X    printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
  1025. X    if ( tp = p->pr_p.p_textp )
  1026. X        printf( "+%3d ", KBYTES( tp->x_size ) ) ;
  1027. X    else
  1028. X        printf( "     " ) ;
  1029. X    /* List process and text real sizes */
  1030. X    printf( "%4d", KBYTES( p->pr_p.p_rssize ) ) ;
  1031. X    if ( tp )
  1032. X        printf( "+%3d %2.0f ", KBYTES( tp->x_rssize ),
  1033. X            percentmem( p ) );
  1034. X    else
  1035. X        printf( "        " ) ;
  1036. X    /* List information obtained from the upage. This includes the process
  1037. X       times and command arguments. */
  1038. X    if ( !p->pr_upag )
  1039. X    {
  1040. X        prcmd( p, 20, -69 ) ;
  1041. X        return ;
  1042. X    }                                       
  1043. X    /* List process time information */
  1044. X# ifdef BSD42
  1045. X    time   = Flg.flg_q ? p->pr_rself.ru_utime.tv_sec :
  1046. X         p->pr_rself.ru_utime.tv_sec + p->pr_rself.ru_stime.tv_sec ;
  1047. X    utime  = Flg.flg_q ? p->pr_rself.ru_utime.tv_usec :
  1048. X         p->pr_rself.ru_utime.tv_usec + p->pr_rself.ru_stime.tv_usec ;
  1049. X    chtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_sec :
  1050. X         p->pr_rchild.ru_utime.tv_sec + p->pr_rchild.ru_stime.tv_sec ;
  1051. X    uchtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_usec :
  1052. X         p->pr_rchild.ru_utime.tv_usec + p->pr_rchild.ru_stime.tv_usec ;
  1053. X    prcpu( time, utime ) ;
  1054. X    if ( chtime != 0L )
  1055. X    {
  1056. X        printf( "+" ) ;
  1057. X        prcpu( chtime, uchtime ) ;
  1058. X    }
  1059. X# else
  1060. X    time   = Flg.flg_q ? p->pr_vself.vm_utime :
  1061. X         p->pr_vself.vm_utime + p->pr_vself.vm_stime ;
  1062. X    chtime = Flg.flg_q ? p->pr_vchild.vm_utime :
  1063. X         p->pr_vchild.vm_utime + p->pr_vchild.vm_stime ;
  1064. X    prcpu( time ) ;
  1065. X    if ( chtime != 0L )
  1066. X    {
  1067. X        printf( "+" ) ;
  1068. X        prcpu( chtime ) ;
  1069. X    }
  1070. X# endif
  1071. X    else
  1072. X        printf( "      " ) ;
  1073. X# ifdef BSD42
  1074. X    if ( time || utime )
  1075. X# else
  1076. X    if ( time )
  1077. X# endif
  1078. X# ifdef SUN
  1079. X        printf( " %2.0f ", (double)p->pr_p.p_pctcpu ) ;
  1080. X# else
  1081. X        printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
  1082. X# endif
  1083. X    else
  1084. X        printf( "    " ) ;
  1085. X    /* Finally, list the process command arguments. */
  1086. X    prcmd( p, 5, -69 ) ;                    
  1087. X}
  1088. X
  1089. X/* CAPITALS - Converts letters in `chp' to upper-case in buffer `buf'. */
  1090. Xcapitals ( chp, buf )
  1091. X
  1092. Xregister char                   *chp ;
  1093. Xregister char                   *buf ;
  1094. X
  1095. X{
  1096. X    while ( *buf = *chp++ )
  1097. X    {
  1098. X        if ( 'a' <= *buf && *buf <= 'z' )
  1099. X            *buf -= 'a' - 'A' ;
  1100. X        buf++ ;
  1101. X    }
  1102. X}
  1103. END_OF_printproc.c
  1104. if test 5849 -ne `wc -c <printproc.c`; then
  1105.     echo shar: \"printproc.c\" unpacked with wrong size!
  1106. fi
  1107. # end of overwriting check
  1108. fi
  1109. if test -f sps.h -a "${1}" != "-c" ; then 
  1110.   echo shar: Will not over-write existing file \"sps.h\"
  1111. else
  1112. echo shar: Extracting \"sps.h\" \(5295 characters\)
  1113. sed "s/^X//" >sps.h <<'END_OF_sps.h'
  1114. X# include    <h/param.h>
  1115. X# include    <h/dir.h>
  1116. X# include    <h/user.h>
  1117. X# include    <h/proc.h>
  1118. X
  1119. X/*
  1120. X** Maximum # of users to be considered. (Should probably be
  1121. X** approximately double the # of users in /etc/passwd.)
  1122. X*/
  1123. X# define    MAXUSERID    100
  1124. X/* Maximum # ttys to be considered ... */
  1125. X# define    MAXTTYS        65
  1126. X/* Maximum user name length ... */
  1127. X# define    UNAMELEN    8
  1128. X/* Maximum process-id not to be considered busy ... */
  1129. X# define    MSPID        2
  1130. X/* # of wait states defined in the `struct info' ... */
  1131. X# ifdef SUN
  1132. X# define    NWAITSTATE    16
  1133. X# else
  1134. X# define    NWAITSTATE    35
  1135. X# endif
  1136. X
  1137. X/* Convert clicks to kbytes ... */
  1138. X# ifdef SUN
  1139. X# define    KBYTES( size )    ((size) << 1)
  1140. X# else
  1141. X# define    KBYTES( size )    ((size) >> (10 - PGSHIFT))
  1142. X# endif
  1143. X
  1144. X/* Standard files to be examined ... */
  1145. X# define    FILE_MEM    "/dev/mem"    /* System physical memory */
  1146. X# define    FILE_KMEM    "/dev/kmem"    /* Kernel virtual memory */
  1147. X# define    FILE_SWAP    "/dev/drum"    /* Swap/paging device */
  1148. X# define    FILE_DEV    "/dev"        /* Directory of tty entries */
  1149. X# define    FILE_SYMBOL    "/vmunix"    /* Symbol file for nlist() */
  1150. X# define    FILE_INFO    "/etc/spsinfo"    /* Sps information file */
  1151. X# define    FILE_PASSWD    "/etc/passwd"    /* User database */
  1152. X
  1153. X/* Structure to hold necessary information concerning a tty ... */
  1154. Xstruct ttyline
  1155. X{
  1156. X    struct tty        *l_addr ;    /* Ptr to tty struct in kmem */
  1157. X    unsigned short        l_pgrp ;    /* Tty process group */
  1158. X    char            l_name[2] ;    /* Tty character name */
  1159. X    dev_t            l_dev ;        /* Tty device # */
  1160. X} ;
  1161. X
  1162. X/* Structure holding a single hash table entry ... */
  1163. Xstruct hashtab
  1164. X{
  1165. X    short            h_uid ;        /* Uid of user entry */
  1166. X    char            h_uname[ UNAMELEN ] ; /* Corresponding name */
  1167. X} ;
  1168. X
  1169. X/*
  1170. X** Format of the standard information file maintained by sps.
  1171. X** This structure is filled in at initialisation time and then is read back
  1172. X** in whenever sps is invoked.
  1173. X** Note that the pointer variables in this structure refer to
  1174. X** kernel virtual addresses, not addresses within sps.
  1175. X** These variable are typed as such so that pointer arithmetic
  1176. X** on the kernel addresses will work correctly.
  1177. X*/
  1178. Xstruct info
  1179. X{    /* Kernel values determining process, tty and upage info ... */
  1180. X    struct proc        *i_proc0 ;    /* address of process table */
  1181. X    int            i_nproc ;    /* length of process table */
  1182. X    struct text        *i_text0 ;    /* address of text table */
  1183. X    int            i_ntext ;    /* length of text table */
  1184. X    struct inode        *i_inode0 ;    /* address of inode table */
  1185. X    int            i_ninode ;    /* length of inode table */
  1186. X    struct buf        *i_swbuf0 ;    /* address of swap buffers */
  1187. X    int            i_nswbuf ;    /* # swap buffers */
  1188. X    struct buf        *i_buf0 ;    /* address of i/o buffers */
  1189. X    int            i_nbuf ;    /* # i/o buffers */
  1190. X    int            i_ecmx ;    /* max physical memory address*/
  1191. X    struct pte        *i_usrptmap ;    /* page table map */
  1192. X    struct pte        *i_usrpt ;    /* page table map */
  1193. X    struct cdevsw        *i_cdevsw ;    /* device switch to find ttys */
  1194. X# ifdef BSD42
  1195. X    struct quota        *i_quota0 ;    /* disc quota structures */
  1196. X    int            i_nquota ;    /* # quota structures */
  1197. X    int            i_dmmin ;    /* The start of the disc map */
  1198. X    int            i_dmmax ;    /* The end of the disc map */
  1199. X    struct mbuf        *i_mbutl ;    /* Start of mbuf area */
  1200. X# else
  1201. X    int            i_hz ;        /* Clock rate */
  1202. X# endif
  1203. X# ifdef CHAOS
  1204. X    caddr_t            i_Chconntab ;    /* Chaos connection table */
  1205. X# endif
  1206. X    /* Kernel addresses are associated with process wait states ... */
  1207. X    caddr_t            i_waitstate[ NWAITSTATE ] ;
  1208. X    /* User names, stored in a hash table ... */
  1209. X    struct hashtab        i_hnames[ MAXUSERID ] ;
  1210. X    /* Tty device info ... */
  1211. X    struct ttyline        i_ttyline[ MAXTTYS ] ;
  1212. X} ;
  1213. X
  1214. X/*
  1215. X** The symbol structure cross-references values read from the kernel with
  1216. X** their place in the info structure, and if such a value is associated with
  1217. X** a process wait state or not.
  1218. X*/
  1219. Xstruct symbol
  1220. X{
  1221. X    char            *s_kname ;    /* Kernel symbol name */
  1222. X    char            s_indirect ;    /* Value requires indirection */
  1223. X    caddr_t            *s_info ;    /* Corresponding info address */
  1224. X    char            *s_wait ;    /* Reason for wait, if any */
  1225. X} ;
  1226. X
  1227. X/* The `user' structure obtained from /dev/mem or /dev/swap ... */
  1228. Xunion userstate
  1229. X{
  1230. X    struct user        u_us ;
  1231. X    char            u_pg[ UPAGES ][ NBPG ] ;
  1232. X} ;
  1233. X
  1234. X/* Information concerning each process filled from /dev/kmem ... */
  1235. Xstruct process
  1236. X{
  1237. X    struct proc        pr_p ;        /* struct proc from /dev/kmem */
  1238. X    struct process        *pr_plink ;    /* Normalised ptrs from above */
  1239. X    struct process        *pr_sibling ;    /* Ptr to sibling process */
  1240. X    struct process        *pr_child ;    /* Ptr to child process */
  1241. X    struct process        *pr_pptr ;    /* Ptr to parent process */
  1242. X# ifdef BSD42
  1243. X    struct rusage        pr_rself ;    /* Read from upage for self */
  1244. X    struct rusage        pr_rchild ;    /* ... and the children */
  1245. X# else
  1246. X    struct vtimes        pr_vself ;    /* Read from upage for self */
  1247. X    struct vtimes        pr_vchild ;    /* ... and the children */
  1248. X# endif
  1249. X    int            pr_files ;    /* # open files */
  1250. X    struct ttyline        *pr_tty ;    /* Associated tty information */
  1251. X    char            *pr_cmd ;    /* Command args, from upage */
  1252. X    int            pr_upag:1 ;    /* Upage was obtained */
  1253. X    int            pr_csaved:1 ;    /* Cmd args saved by malloc() */
  1254. X} ;
  1255. X
  1256. X/* Structure to hold summarising information ... */
  1257. Xstruct summary
  1258. X{
  1259. X    long            sm_ntotal ;    /* Total # processes */
  1260. X    long            sm_ktotal ;    /* Total virtual memory */
  1261. X    long            sm_nbusy ;    /* # busy processes */
  1262. X    long            sm_kbusy ;    /* Busy virtual memory */
  1263. X    long            sm_nloaded ;    /* # loaded processes */
  1264. X    long            sm_kloaded ;    /* Active resident memory */
  1265. X    long            sm_nswapped ;    /* # swapped processes */
  1266. X    long            sm_kswapped ;    /* Size totally swapped out */
  1267. X} ;
  1268. END_OF_sps.h
  1269. if test 5295 -ne `wc -c <sps.h`; then
  1270.     echo shar: \"sps.h\" unpacked with wrong size!
  1271. fi
  1272. # end of overwriting check
  1273. fi
  1274. if test -f waitingfor.c -a "${1}" != "-c" ; then 
  1275.   echo shar: Will not over-write existing file \"waitingfor.c\"
  1276. else
  1277. echo shar: Extracting \"waitingfor.c\" \(6584 characters\)
  1278. sed "s/^X//" >waitingfor.c <<'END_OF_waitingfor.c'
  1279. X# include       "sps.h"
  1280. X# include       <h/text.h>
  1281. X# ifdef NFS
  1282. X# include       <h/vnode.h>
  1283. X# include       <ufs/inode.h>
  1284. X# else
  1285. X# include       <h/inode.h>
  1286. X# endif NFS
  1287. X# include       <h/ioctl.h>
  1288. X# include       <h/tty.h>
  1289. X# include       <h/buf.h>
  1290. X# ifdef BSD42
  1291. X# ifndef NFS
  1292. X# include       <h/quota.h>
  1293. X# endif NFS
  1294. X# include       <h/mbuf.h>
  1295. X# include       <h/socket.h>
  1296. X# include       <h/socketvar.h>
  1297. X# endif BSD42
  1298. X
  1299. X/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  1300. X# define        INRANGE( w, a1, a2 ) \
  1301. X            ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  1302. X
  1303. X/* NFS changes incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  1304. X
  1305. X/* WAITINGFOR - Determine what a process is waiting for and describe it. */
  1306. Xchar    *waitingfor ( p )
  1307. X
  1308. Xstruct process                  *p ;
  1309. X
  1310. X{
  1311. X    register caddr_t        w ;
  1312. X    register struct ttyline *lp ;
  1313. X    register struct symbol  *s ;
  1314. X    register char           *cp ;
  1315. X# ifdef BSD42
  1316. X    struct socket           sc ;
  1317. X# endif
  1318. X    int            rc ;
  1319. X    static char             wbuf[ 8 ] ;
  1320. X    extern struct info      Info ;
  1321. X    extern struct symbol    Symbollist[] ;
  1322. X    char                    *sprintf() ;
  1323. X
  1324. X    w = p->pr_p.p_wchan ;
  1325. X    if ( !w )
  1326. X        return ( "null" ) ;
  1327. X    /* Waiting for a child process, alternatively in a vfork() ? */
  1328. X    if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
  1329. X        return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
  1330. X    /* Waiting for a page to be brought in ? */
  1331. X    if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
  1332. X        return ( "swap" ) ;
  1333. X    /* Waiting for discio through a block device to complete ? */
  1334. X    if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
  1335. X        /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
  1336. X           IS GENERALLY MEANT HERE. */
  1337. X        return ( "discio" ) ;
  1338. X    /* Waiting for a text page to be brought in ? */
  1339. X    if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
  1340. X        return ( "swtext" ) ;
  1341. X# ifdef BSD42
  1342. X# ifndef NFS
  1343. X    /* Waiting for an event associated with the quota system ? */
  1344. X    if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
  1345. X        return ( "quota" ) ;
  1346. X# endif NFS
  1347. X# endif BSD42
  1348. X    /* Waiting for tty I/O ? If so, find which tty it is */
  1349. X    for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  1350. X        if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
  1351. X        {
  1352. X            switch ( (int)w - (int)lp->l_addr )
  1353. X            {
  1354. X                case (int)&((struct tty*)0)->t_rawq :
  1355. X                    /* Read from a tty or slave pty */
  1356. X                    cp = "rtty??" ;
  1357. X                    break ;
  1358. X                case (int)&((struct tty*)0)->t_outq :
  1359. X                    /* Write to a tty or slave pty */
  1360. X                    cp = "wtty??" ;
  1361. X                    break ;
  1362. X                case (int)&((struct tty*)0)->t_state :
  1363. X                    /* Tty not open */
  1364. X                    cp = "otty??" ;
  1365. X                    break ;
  1366. X                case (int)&((struct tty*)0)->t_outq.c_cf :
  1367. X                    /* Read from a controller pty */
  1368. X                    cp = "rpty??" ;
  1369. X                    break ;
  1370. X                case (int)&((struct tty*)0)->t_rawq.c_cf :
  1371. X                    /* Write to a controller pty */
  1372. X                    cp = "wpty??" ;
  1373. X                    break ;
  1374. X                default :
  1375. X                    cp = "?tty??" ;
  1376. X                    break ;
  1377. X            }
  1378. X            cp[4] = lp->l_name[0] ;
  1379. X            cp[5] = lp->l_name[1] ;
  1380. X            return ( cp ) ;
  1381. X        }
  1382. X    /* Waiting for an inode ? */
  1383. X    if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
  1384. X        switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
  1385. X        {
  1386. X# ifdef BSD42
  1387. X# ifndef NFS
  1388. X            case (int)&((struct inode*)0)->i_exlockc :
  1389. X                /* Exclusive lock on this inode */
  1390. X                return ( "exlock" ) ;
  1391. X            case (int)&((struct inode*)0)->i_shlockc :
  1392. X                /* Shared lock on this inode */
  1393. X                return ( "shlock" ) ;
  1394. X# endif NFS
  1395. X# else
  1396. X            case 1 :
  1397. X                return ( "wpipe" ) ;
  1398. X            case 2 :
  1399. X                return ( "rpipe" ) ;
  1400. X            case (int)&((struct inode*)0)->i_un.i_group.g_datq :
  1401. X                return ( "rmux" ) ;
  1402. X# endif BSD42
  1403. X            default :
  1404. X                /* Inode probably locked */
  1405. X                return ( "inode" ) ;
  1406. X        }
  1407. X# ifdef BSD42
  1408. X    /* Waiting for a structure inside an mbuf ? If so, try to find why */
  1409. X    if ( INRANGE( w, Info.i_mbutl,
  1410. X    &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
  1411. X        switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
  1412. X            - (int)&((struct mbuf*)0)->m_dat[0] )
  1413. X        {
  1414. X            case (int)&((struct socket*)0)->so_timeo :
  1415. X                /* Socket timeout event - Guess why */
  1416. X                rc = getsocket( (struct socket*)(w
  1417. X                    - (int)&((struct socket*)0)->so_timeo),
  1418. X                        &sc ) ;
  1419. X                return ( rc && (sc.so_state & SS_ISCONNECTING)
  1420. X                    ? "connct" 
  1421. X                    : rc && ((sc.so_options & SO_ACCEPTCONN)
  1422. X                      && !sc.so_qlen)
  1423. X                    ? "accept" : "socket" ) ;
  1424. X            case (int)&((struct socket*)0)->so_rcv.sb_cc :
  1425. X                /* Read from an empty socket. Here we actually
  1426. X                   attempt to determine whether the socket
  1427. X                   structure in question really does refer to
  1428. X                   a socket, or whether it is in fact a pipe
  1429. X                   in disguise. */
  1430. X                return ( getsocket( (struct socket*)(w
  1431. X                    - (int)&((struct socket*)0)->so_rcv.sb_cc),
  1432. X                        &sc )
  1433. X                    && sc.so_type == SOCK_STREAM
  1434. X#ifdef BSD43
  1435. X                    && ((sc.so_state
  1436. X                        & (SS_ISCONNECTED|SS_CANTSENDMORE))
  1437. X                        == (SS_ISCONNECTED|SS_CANTSENDMORE))
  1438. X#else
  1439. X                    && !sc.so_rcv.sb_hiwat
  1440. X                    && !sc.so_rcv.sb_mbmax
  1441. X                    && (sc.so_state
  1442. X                        & (SS_ISCONNECTED|SS_CANTRCVMORE))
  1443. X#endif BSD43
  1444. X                    ? "rpipe" : "rsockt" ) ;
  1445. X            case (int)&((struct socket*)0)->so_snd.sb_cc :
  1446. X                /* Write to a full socket. Again, we try
  1447. X                   to determine whether or not this is a
  1448. X                   real socket or a pipe. */
  1449. X                return ( getsocket( (struct socket*)(w
  1450. X                    - (int)&((struct socket*)0)->so_snd.sb_cc),
  1451. X                        &sc )
  1452. X#ifdef BSD43
  1453. X                    && sc.so_type == SOCK_STREAM
  1454. X                    && ((sc.so_state
  1455. X                        & (SS_ISCONNECTED|SS_CANTRCVMORE))
  1456. X                        == (SS_ISCONNECTED|SS_CANTRCVMORE))
  1457. X#else
  1458. X                    && sc.so_rcv.sb_hiwat == 2048
  1459. X                    && sc.so_rcv.sb_mbmax == 4096
  1460. X                    && (sc.so_state
  1461. X                        & (SS_ISCONNECTED|SS_CANTSENDMORE))
  1462. X#endif BSD43
  1463. X                    ? "wpipe" : "wsockt" ) ;
  1464. X            default :
  1465. X                /* Other mbuf event */
  1466. X                return ( "mbuf" ) ;
  1467. X        }
  1468. X# endif BSD42
  1469. X    /* Look in the symbol table for known wait addresses. */
  1470. X    for ( s = Symbollist ; s->s_kname ; s++ )
  1471. X        if ( s->s_wait && w == *s->s_info )
  1472. X            return ( s->s_wait ) ;  
  1473. X    /* No reason for the wait state has been found.
  1474. X       Return the wait channel as a hexadecimal address. */
  1475. X# ifdef SUN
  1476. X    (void)sprintf( wbuf, "x%05x", w ) ;
  1477. X# else
  1478. X    (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
  1479. X# endif SUN
  1480. X    return ( wbuf ) ;
  1481. X}
  1482. X
  1483. X# ifdef BSD42
  1484. X/*
  1485. X** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
  1486. X** identified by `ks' into the buffer `s'.
  1487. X*/
  1488. Xgetsocket ( ks, s )
  1489. X
  1490. Xstruct socket                   *ks ;
  1491. Xstruct socket                   *s ;
  1492. X
  1493. X{
  1494. X    extern int              Flkmem ;
  1495. X
  1496. X    memseek( Flkmem, (long)ks ) ;
  1497. X    return ( read( Flkmem, (char*)s, sizeof( struct socket ) )
  1498. X        == sizeof( struct socket ) ) ;
  1499. X}
  1500. X# endif BSD42
  1501. END_OF_waitingfor.c
  1502. if test 6584 -ne `wc -c <waitingfor.c`; then
  1503.     echo shar: \"waitingfor.c\" unpacked with wrong size!
  1504. fi
  1505. # end of overwriting check
  1506. fi
  1507. echo shar: End of archive 2 \(of 3\).
  1508. cp /dev/null ark2isdone
  1509. MISSING=""
  1510. for I in 1 2 3 ; do
  1511.     if test ! -f ark${I}isdone ; then
  1512.     MISSING="${MISSING} ${I}"
  1513.     fi
  1514. done
  1515. if test "${MISSING}" = "" ; then
  1516.     echo You have unpacked all 3 archives.
  1517.     rm -f ark[1-9]isdone
  1518. else
  1519.     echo You still need to unpack the following archives:
  1520.     echo "        " ${MISSING}
  1521. fi
  1522. ##  End of shell archive.
  1523. exit 0
  1524. -- 
  1525.  
  1526. Rich $alz            "Anger is an energy"
  1527. Cronus Project, BBN Labs    rsalz@bbn.com
  1528. Moderator, comp.sources.unix    sources@uunet.uu.net
  1529.